---
breakpoint: tablet
title: Migrating from Fannypack
path: /migrating-from-fannypack/
---

# Migrating from Fannypack

If you are migrating from Fannypack, there are quite a few notable breaking changes. This guide aims to help you migrate to Bumbag. If you feel like there is anything missing from this guide, feel free to raise a pull request.

## Upgrading incrementally

It's recommended to upgrade to Bumbag incrementally, meaning that Fannypack and Bumbag will co-exist until Bumbag takes over.

If you wish to upgrade incrementally, you can install the `bumbag` package:

```
npm install bumbag
```

And then, set up Bumbag in your app base:

```jsx
// Bumbag
import { Provider as BumbagProvider } from 'bumbag';
// Fannypack
import { ThemeProvider } from 'fannypack';

const oldTheme = { ... };
const newTheme = { ... };

const App = () => (
  <ThemeProvider theme={oldTheme}>
    <BumbagProvider theme={newTheme}>
      Hello world!
    </BumbagProvider>
  </ThemeProvider>
);
```

Then you can start incrementally migrating your components like so:

```jsx
- import { Box } from 'fannypack';
+ import { Box } from 'bumbag';
import { Button } from 'fannypack';

function Example() {
  return (
    <Box>
      <Button>Hello world!</Button>
    </Box>
  )
}
```

## Breaking changes

### General: `ThemeProvider` to `Provider`

We have renamed the `<ThemeProvider>` component to `<Provider>`.

[See more...](/docs/getting-started)

##### v4

```jsx
import { ThemeProvider } from 'fannypack';

const App = () => (
  <ThemeProvider>
    Hello world!
  </ThemeProvider>
);
```

##### v5

```jsx
import { Provider } from 'bumbag';

const App = () => (
  <Provider>
    Hello world!
  </Provider>
);
```

<Divider />

### Theming: `.base` to `.styles.base`

We have renamed the `base` attribute in the global theme to `styles.base`.

##### v4

```jsx
const theme = {
  Box: {
    base: {
      backgroundColor: 'red'
    }
  }
}
```

##### v5

```jsx
const theme = {
  Box: {
    styles: {
      base: {
        backgroundColor: 'red'
      }
    }
  }
}
```

[See more...](/theming)

<Divider />

### Theming: No more support for inline functions in the `css` attribute.

We have removed support for inline functions within the `css` attribute. You will now have to retrieve props by converting the attribute to a function.

##### v4

```jsx
const theme = {
  Box: {
    base: css`
      color: ${palette('primary')};

      ${props => props.error && css`
        background-color: red;
      `}
    `
  }
}
```

##### v5

```jsx
const theme = {
  Box: {
    styles: {
      base: props => css`
        color: ${palette('primary')(props)};

        ${props.error && css`
          background-color: red;
        `}
      `
    }
  }
}
```

<Divider />

### Theming: `layout.<viewport>Breakpoint` to `breakpoints.<viewport>`

We have moved where breakpoints are defined in the global theme.

##### v4

In v4, they were placed under the `layout` attribute.

```jsx
const theme = {
  layout: {
    mobileBreakpoint: 480,
    tabletBreakpoint: 768,
    desktopBreakpoint: 1024,
    widescreenBreakpoint: 1200,
    fullHDBreakpoint: 1440,
  }
};
```

##### v5

Now they are placed under a dedicated `breakpoints` attribute.

```jsx
const theme = {
  breakpoints: {
    mobile: 480,
    tablet: 768,
    desktop: 1024,
    widescreen: 1200,
    fullHD: 1440
  }
};
```

[See more...](/breakpoints)

<Divider />

### Theming: `layout.gapFactor` to `Columns.defaultProps.spacing`

The `gapFactor` attribute was only used for the `Columns` component. So we renamed it to a `spacing` prop to put on the `Columns` component.

##### v4

```jsx
const theme = {
  layout: {
    gapFactor: '1rem'
  }
};
```

##### v5

```jsx
const theme = {
  Columns: {
    defaultProps: {
      spacing: 'major-2'
    }
  }
};
```

<Divider />

### Theming: `layout.<minor|major>Unit` to `spacing.<minor|major>Unit`

The `layout.minorUnit` and `layout.majorUnit` attributes are renamed to `spacing.minorUnit` and `spacing.majorUnit`

##### v4

```jsx
const theme = {
  layout: {
    minorUnit: 4,
    majorUnit: 8
  }
};
```

##### v5

```jsx
const theme = {
  spacing: {
    minorUnit: 4,
    majorUnit: 8
  }
};
```

<Divider />

### Theming: `global.fontFamily` to `fonts.default`

We have moved the `global.fontFamily` attribute to `fonts.default`

##### v4

```jsx
const theme = {
  global: {
    fontFamily: "'Lato', system-ui, sans-serif"
  }
}
```

##### v5

```jsx
const theme = {
  fonts: {
    default: "'Lato', system-ui, sans-serif"
  }
}
```

### Theming: Removed `webFontLoader`

Web Font Loader was removed in favour of direct Google Font imports with font swapping.

##### v4

Previously, web font loader was used to import Google Fonts.

```jsx
const theme = {
  global: {
    fontFamily: "'Lato', system-ui, sans-serif",
    fallbackFontFamily: "system-ui, sans-serif"
  },
  webFontLoader: {
    google: {
      families: ['Lato:400,700,900']
    }
  }
}
```

##### v5

Now, you import the font(s) directly from Google Fonts.

[Click here to see a list of Google Fonts](https://fonts.google.com/)

```jsx
const theme = {
  fonts: {
    importUrls: ['https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&display=swap'],
    default: "'Lato', system-ui, sans-serif"
  }
}
```

<Divider />

### Box: `hiddenBreakpoint` to `<Hide>`

The `hiddenBreakpoint` prop on components has been converted to a `<Hide>` component.

##### v4

```jsx
<Box hiddenBreakpoint="tablet">Hidden below tablet</Box>
```

##### v5

```jsx
<Hide below="tablet">Hidden below tablet</Hide>
```

<Divider />

### Box: `showBreakpoint` to `<Show>`

The `showBreakpoint` prop on components has been converted to a `<Show>` component.

##### v4

```jsx
<Box showBreakpoint="tablet">Shown above tablet</Box>
```

##### v5

```jsx
<Show above="tablet">Shown above tablet</Show>
```

<Divider />

### LayoutSet: `LayoutSet` to `Stack`

The `LayoutSet` component has been renamed to `Stack`.

```jsx
<LayoutSet>
  <Box>Evenly</Box>
  <Box>Spaced</Box>
  <Box>Components</Box>
</LayoutSet>
```

##### v5

```jsx
<Stack>
  <Box>Evenly</Box>
  <Box>Spaced</Box>
  <Box>Components</Box>
</Stack>
```

<Divider />

### Pane: Removed `<Pane>`

We have removed `Pane` in v5.

If you still want borders, then use the [`border` attribute](/the-box-primitive/borders/) on box.

If you still want shadow, then use the [`altitude` attribute](/the-box-primitive/altitudes/) on box.

If you still want border radius, then use the [`borderRadius` attribute](/the-box-primitive/border-radius/) on box.

##### v4

```jsx
<Pane border="shadow">Hello world</Pane>
```

##### v5

```jsx
<Box altitude="100" borderRadius="default">Hello world</Box>
```

<Divider />

### Alert: Removed `hasTint`

We have removed the `hasTint` prop on the Alert component in favour of `variant`.

##### v4

```jsx
<Alert hasTint type="danger">Hello world</Alert>
```

##### v5

```jsx
<Alert variant="tint" type="danger">Hello world</Alert>
```

<Divider />

### Avatar: `kind` to `variant`

We have renamed the `kind` prop to `variant`

##### v4

```jsx
<Avatar kind="circle">
```

##### v5

```jsx
<Avatar variant="circle">
```

<Divider />

### Badge: `isAbsolute` to `isAttached`

##### v4

```jsx
<Badge isAbsolute>1</Badge>
```

##### v5

```jsx
<Badge isAttached>1</Badge>
```

<Divider />

### Breadcrumb: `Breadcrumb.Step` to `Breadcrumb.Item`

The `Breadcrumb.Step` component was renamed to `Breadcrumb.Item`.

If you have been using links in your breadcrumbs, you will also have to create separate `Breadcrumb.Link` components.

##### v4

```jsx
<Breadcrumb>
  <Breadcrumb.Step href="#">Home</Breadcrumb.Step>
  <Breadcrumb.Step href="#">Business</Breadcrumb.Step>
  <Breadcrumb.Step href="#" isCurrent>Staff members</Breadcrumb.Step>
</Breadcrumb>
```

##### v5

```jsx
<Breadcrumb>
  <Breadcrumb.Item>
    <Breadcrumb.Link href="#">Home</Breadcrumb.Link>
  </Breadcrumb.Item>
  <Breadcrumb.Item>
    <Breadcrumb.Link href="#">Business</Breadcrumb.Link>
  </Breadcrumb.Item>
  <Breadcrumb.Item isCurrent>
    <Breadcrumb.Link href="#">Staff Members</Breadcrumb.Link>
  </Breadcrumb.Item>
</Breadcrumb>
```

<Divider />

### Button: `kind` to `variant`

The `kind` prop has been renamed to `variant`.

##### v4

```jsx
<Button kind="outlined" palette="primary">Hello world</Button>
```

##### v5

```jsx
<Button variant="outlined" palette="primary">Hello world</Button>
```

<Divider />

### Button Theme: Removed `Button.interactive`

The `Button.interactive` theme key has been removed in favour of pseudo based keys.

##### v4

```jsx
const theme = {
  Button: {
    interactive: css`
      &:focus {
        ...
      }

      &:hover {
        ...
      }

      &:hover:active {
        ...
      }
    `
  }
}
```

##### v5

```jsx
const theme = {
  Button: {
    focus: css`
      ...
    `,
    hover: css`
      ...
    `,
    hoveractive: css`
      ...
    `
  }
}
```

<Divider />

### CalloutOverlay: Removed `CalloutOverlay`

Removed `CalloutOverlay` in favor of `Callout.Overlay` and the `Overlay` utility.

##### v4

```jsx
<Overlay.Container>
  {overlay => (
    <Box>
      <Button use={Overlay.Toggle} {...overlay}>
        Click me
      </Button>
      <CalloutOverlay
        title="This is a title"
        {...overlay}
      >
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue, ultrices
        eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum consectetur lectus
        augue sit amet justo.
      </CalloutOverlay>
    </Box>
  )}
</Overlay.Container>
```

##### v5


```jsx
<Overlay.State>
  <Overlay.Disclosure use={Button}>Open callout</Overlay.Disclosure>
  <Callout.Overlay title="This is a title">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue, ultrices
    eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum consectetur lectus
    augue sit amet justo.
  </Callout.Overlay>
</Overlay.State>
```

<Divider />

### Card: `elevation` to `altitude`

The `elevation` prop has been renamed to `altitude`.

##### v4

```jsx
<Card elevation="100">
```

##### v5

```jsx
<Card altitude="100">
```

<Divider />

### Card: `headerActions` to `headerAddon`

The `headerActions` prop has been renamed to `headerAddon`.

##### v4

```jsx
<Card headerActions={...}>
```

##### v5

```jsx
<Card headerAddon={...}>
```

<Divider />

### HighlightedCode: Moved to `bumbag-addon-highlighted-code`

We have moved the `HighlightedCode` component to `bumbag-addon-highlighted-code` to save some bundle size.

##### v4

```jsx
import { HighlightedCode } from 'fannypack';
```

##### v5

```jsx
// First, install the package
npm install bumbag-addon-highlighted-code

// Then, import it accordingly
import { HighlightedCode } from 'bumbag-addon-highlighted-code';
```

<Divider />

### Column: Moved to `Columns.Column`

We have moved the `Column` component to a sub-component of `Columns`.

##### v4

```jsx
<Column>
```

##### v5

```jsx
<Columns.Column>
```

<Divider />

### DialogModal: Removed `DialogModal`

Removed `DialogModal` in favor of `Dialog.Modal` and the `Modal` utility.

##### v4

```jsx
<Modal.Container>
  {modal => (
    <Box>
      <Button use={Modal.Show} {...modal}>
        Click me
      </Button>
      <DialogModal {...modal}>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue,
        ultrices eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum
        consectetur lectus augue sit amet justo.
      </DialogModal>
    </Box>
  )}
</Modal.Container>
```

##### v5


```jsx
<Modal.State>
  <Modal.Disclosure use={Button}>Open dialog</Modal.Disclosure>
  <Dialog.Modal title="This is a title">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse diam ipsum, cursus id placerat congue, ultrices
    eget lectus. Duis posuere, lacus sed tristique commodo, sapien turpis mollis nunc, vestibulum consectetur lectus
    augue sit amet justo.
  </Dialog.Modal>
</Modal.State>
```

<Divider />

### Divider: Removed `content`

We have removed the `content` prop on `Divider`.

<Divider />

### Divider: `isVertical` to `orientation`

We have repurposed the `isVertical` prop to `orientation`.

##### v4

```jsx
<Divider isVertical />
```

##### v5

```jsx
<Divider orientation="vertical" />
```

<Divider />

### FieldSet: Renamed to `FieldStack`

##### v4

```jsx
<FieldSet>
```

##### v5

```jsx
<FieldStack>
```

<Divider />

### FieldSet: `isHorizontal` to `orientation`

##### v4

```jsx
<FieldSet isHorizontal />
```

##### v5

```jsx
<FieldStack orientation="horizontal" />
```

<Divider />

### FieldWrapper: `tooltipTrigger` to `tooltipTriggerComponent`

We have renamed the `tooltipTrigger` prop to `tooltipTriggerComponent`

##### v4

```jsx
<FieldWrapper tooltipTrigger={<Button size="small">Tooltip</Button>} />
```

##### v5

```jsx
<FieldWrapper tooltipTriggerComponent={<Button size="small">Tooltip</Button>} />
```

<Divider />

### Group: `isVertical` to `orientation`

We have renamed the `isVertical` prop to `orientation`.

##### v4

```jsx
<Group isVertical />
```

##### v5

```jsx
<Group orientation="vertical" />
```

<Divider />

### Group: `verticalAt` to `verticalBelow`

We have renamed the `verticalAt` prop to `verticalBelow`.

##### v4

```jsx
<Group verticalAt="desktop" />
```

##### v5

```jsx
<Group verticalBelow="desktop" />
```

<Divider />

### Hidden: Removed `Hidden`

We have removed the `Hidden` utility in favour of the [`Disclosure` utility](/utilities/disclosure).

##### v4

```jsx
<Hidden.Container>
  {hidden => (
    <Box>
      <Button use={Hidden.Toggle} {...hidden}>Toggle</Button>
      <Hidden {...hidden}>
        Hello world
      </Hidden>
    </Box>
  )}
</Hidden.Container>
```

##### v5

```jsx
<Disclosure.State>
  <Disclosure>Toggle</Disclosure>
  <Disclosure.Content>Hello world</Disclosure.Content>
</Disclosure.State>
```

<Divider />

### Icon: `size` to `fontSize`

The `size` prop has been renamed to `fontSize`.

##### v4

```jsx
<Icon size="400">
```

##### v5

```jsx
<Icon fontSize="400">
```

<Divider />

### List: `isVertical` to `orientation`

We have renamed the `isVertical` prop to `orientation`.

##### v4

```jsx
<List isVertical>
```

##### v5

```jsx
<List orientation="vertical">
```

<Divider />

### Markdown: Moved to `bumbag-addon-markdown`

We have moved the `Markdown` component to `bumbag-addon-markdown` to save some bundle size.

##### v4

```jsx
import { Markdown } from 'fannypack';
```

##### v5

```jsx
// First, install the package
npm install bumbag-addon-markdown

// Then, import it accordingly
import { Markdown } from 'bumbag-addon-markdown';
```

<Divider />

### Modal: `Modal.Container` to `Modal.State`

We have repurposed the `Modal.Container` utility to `Modal.State`.

##### v4

```jsx
<Modal.Container>
  {({ isVisible, show, hide, toggle, ... })} => (...)
</Modal.Container>
```

##### v5

```jsx
<Modal.State>
  {({ visible, show, hide, toggle, ... })} => (...)
</Modal.State>
```

<Divider />

### Overlay: `Overlay.Container` to `Overlay.State`

We have repurposed the `Overlay.Container` utility to `Overlay.State`.

##### v4

```jsx
<Overlay.Container>
  {({ isVisible, show, hide, toggle, ... })} => (...)
</Overlay.Container>
```

##### v5

```jsx
<Overlay.State>
  {({ visible, show, hide, toggle, ... })} => (...)
</Overlay.State>
```

<Divider />

### PageContent: `Page.Content` to `PageContent`

We have renamed the `Page.Content` component to `PageContent`.

##### v4

```jsx
<Page.Content>
```

##### v5

```jsx
<PageContent>
```

<Divider />

### PageWithSidebar: `Page.WithSidebar` to `PageWithSidebar`

We have renamed the `Page.WithSidebar` component to `PageWithSidebar`.

##### v4

```jsx
<Page.WithSidebar>
```

##### v5

```jsx
<PageWithSidebar>
```

<Divider />

### PageWithSidebar: `sidebarContent` to `sidebar`

##### v4

```jsx
<Page.WithSidebar sidebarContent={...}>
```

##### v5

```jsx
<PageWithSidebar sidebar={...}>
```

<Divider />

### Popover: `Popover` to `Popover.State` & `Popover`

We have repurposed the `Popover` component to use `Popover.State` along with a `Popover.Disclosure` component.

The `Popover` component no longer handles it's state internally.

##### v4

```jsx
<Popover content={<Text>What was the best thing that happened to you today?</Text>}>
  <Button>Open Popover</Button>
</Popover>
```

##### v5

```jsx
<Popover.State>
  <Popover.Disclosure use={Button}>Open Popover</Popover.Disclosure>
  <Popover>
    What was the best thing that happened to you today?
  </Popover>
</Popover.State>
```

<Divider />

### Rating: `maxRating` to `maxValue`

We have renamed the `maxRating` prop to `maxValue`.

##### v4

```jsx
<Rating maxRating={10}>
```

##### v5

```jsx
<Rating maxValue={10}>
```

<Divider />

### Rating: `onRate` to `onChange`

We have renamed the `onRate` prop to `onChange`.

##### v4

```jsx
<Rating onRate={() => {}}>
```

##### v5

```jsx
<Rating onChange={() => {}}>
```

<Divider />

### SelectMenu: `useTags` to `hasTags`

We have renamed the `useTags` prop to `hasTags`.

##### v4

```jsx
<SelectMenu useTags>
```

##### v5

```jsx
<SelectMenu hasTags>
```

<Divider />

### SelectMenu: `loadQuery` to `loadVariables`

##### v4

```jsx
<SelectMenu loadQuery={{ key: 'value' }}>
```

##### v5

```jsx
<SelectMenu loadVariables={{ key: 'value' }}>
```

<Divider />

### SelectMenu: `data` to `variables`

Inside the `loadOptions` prop, the `data` attribute has been renamed to `variables`.

##### v4

```jsx
<SelectMenu loadOptions={({ searchText, page, data }) => ...}>
```

##### v5

```jsx
<SelectMenu loadOptions={({ searchText, page, variables }) => ...}>
```

<Divider />

### SelectMenu: `isSearchable` to `hasSearch`

The `isSearchable` prop has been renamed to `hasSearch`.

##### v4

```jsx
<SelectMenu isSearchable>
```

##### v5

```jsx
<SelectMenu hasSearch>
```

<Divider />

### Set: `isVertical` to `orientation`

The `isVertical` prop has been renamed to `orientation`.

##### v4

```jsx
<Set isVertical>
```

##### v5

```jsx
<Set orientation="vertical">
```

<Divider />

### Sidebar: `Sidebar` to `Drawer`

The `Sidebar` utility has been renamed to `Drawer`.

`Sidebar.Container` has also been renamed to `Drawer.State`.

##### v4

```jsx
<Sidebar.Container>
  {sidebar => (
    <Box>
      <Button use={Sidebar.Show} {...sidebar}>
        Toggle
      </Button>
      <Sidebar {...sidebar}>
        This is a side drawer
      </Sidebar>
    </Box>
  )}
</Sidebar.Container>
```

##### v5

```jsx
<Drawer.State>
  <Drawer.Disclosure>Toggle</Drawer.Disclosure>
  <Drawer>
    This is a side drawer
  </Drawer>
</Drawer.State>
```

<Divider />

### Tabs: `Tabs.Container` to `Tabs`

The `Tabs.Container` component has been repurposed to `Tabs`.

##### v4

```jsx
<Tabs.Container>
  {tabs => (
    ...
  )}
</Tabs.Container>
```

##### v5


```jsx
<Tabs>
  ...
</Tabs>
```

<Divider />

### Tabs: `Tabs` to `Tabs.List`

##### v4

```jsx
<Tabs.Container>
  {tabs => (
    <Tabs>
      <Tabs.Tab tab="dogs" {...tabs}>
        Dogs
      </Tabs.Tab>
      <Tabs.Tab tab="cats" {...tabs}>
        Cats
      </Tabs.Tab>
      <Tabs.Tab tab="parrots" {...tabs}>
        Parrots
      </Tabs.Tab>
    </Tabs>
  )}
</Tabs.Container>
```

##### v5

```jsx
<Tabs selectedId="tab1">
  <Tabs.List>
    <Tabs.Tab tabId="tab1">Dogs</Tabs.Tab>
    <Tabs.Tab tabId="tab2">Cats</Tabs.Tab>
    <Tabs.Tab tabId="tab3">Parrots</Tabs.Tab>
  </Tabs.List>
</Tabs>
```

<Divider />

### Tabs: `type` to `variant`

The `type` prop has been renamed to `variant`

##### v4

```jsx
<Tabs type="boxed">
```

##### v5

```jsx
<Tabs.List variant="boxed">
```

<Divider />

### Tabs.Panel: `tab` to `tabId`

The `tab` prop has been renamed to `tabId`

##### v4

```jsx
<Tabs.Panel tab="cats">
```

##### v5

```jsx
<Tabs.Panel tabId="cats">
```

<Divider />

### Tabs.Tab: `tab` to `tabId`

The `tab` prop has been renamed to `tabId`

##### v4

```jsx
<Tabs.Tab tab="cats">
```

##### v5

```jsx
<Tabs.Tab tabId="cats">
```

<Divider />

### Tag: `kind` to `variant`

The `kind` prop has been renamed to `variant`

##### v4

```jsx
<Tag variant="outlined">
```

##### v5

```jsx
<Tag variant="outlined">
```

<Divider />

### Toast: Now requires a `ToastManager`

The Toast component now requires a `ToastManager` to render the toasts.

```jsx
import { Provider, ToastManager } from 'bumbag';

const App = () => (
  <Provider theme={theme}>
    // ... your app
    <ToastManager />
  </Provider>
);
```

<Divider />

### Toast: `Toast.Container` & `withToasts` to `useToasts`

##### v4

```jsx
<Toast.Container>
  {toasts => (
    <Button
      onClick={() => toasts.success({ title: 'Message sent' })}
    >
      Add toast
    </Button>
  )}
</Toast.Container>
```

##### v5

```jsx
function Example() {
  const toasts = useToasts();

  return (
    <Button
      onClick={() => toasts.success({ title: 'Message sent' })}
    >
      Add toast
    </Button>
  )
}
```

<Divider />

### Tooltip: Now wraps over children

The `Tooltip` component now wraps over it's children.

##### v4

```jsx
<Button>
  Hover on me
  <Tooltip>Hello world!</Tooltip>
</Button>
```

##### v5

```jsx
<Tooltip content="Hello world">
  <Button>Hover on me</Button>
</Tooltip>
```





